<template>
  <div class="map-container">
    <div class="map" :id="mapId"></div>
    <div class="top">
      <div class="search">
        <div class="tip">请输入关键字</div>
        <input id="tipinput" type="text" />
      </div>
      <div id="output"></div>
    </div>

    <div class="edit" @click="onClickSE">{{ isEdit ? '结束' : '新建' }}</div>
  </div>
</template>

<script>
const polygonLayer = {} // 临时保存polygon集合
export default {
  name: 'EditMap',
  props: {

  },
  data() {
    return {
      type: null,
      isEdit: false,
      mapId: 'editMap' + new Date().getTime() + parseInt(Math.random() * 1000)
    };
  },
  computed: {
    sideTheme() {
      return this.$store.state.settings.sideTheme;
    }
  },
  mounted() {
    if (window.AMap) {
      this.initMap();
    } else {
      window.addEventListener('mapReady', this.initMap);
    }
  },
  beforeDestroy() {
    this.map && this.map.destroy();
    window.removeEventListener('mapReady', this.initMap);
  },
  methods: {
    onClickSE() {
      if (!this.type) {
        this.$modal.msgWarning('请选中编辑');
        return;
      }
      if (this.isEdit) {
        // 结束编辑
        if (this.type == 'polygon') {
          this.polygonEditor.close();
          const polygon = this.polygonEditor.getTarget();
          if (polygon) {
            // 如果是新建对象就添加事件
            const has = this.polygons.find((item) => item == polygon);
            if (!has) {
              polygon.setOptions(this.polygonStyle);
              polygon.on('rightclick', this.rightClickByPolygon);
              polygon.on('dblclick', this.dblClickByPolygon);
              this.map.add(polygon);
              this.polygons.push(polygon);
            }
          }
        } else if (this.type == 'polyline') {
          this.polylineEditor.close();
          const polyline = this.polylineEditor.getTarget();
          if (polyline) {
            // 如果是新建对象就添加事件
            const has = this.polylines.find((item) => item == polyline);
            if (!has) {
              polyline.setOptions(this.polylineStyle);
              polyline.on('rightclick', this.rightClickByPolyline);
              polyline.on('dblclick', this.dblClickByPolyline);
              this.map.add(polyline);
              this.polylines.push(polyline);
            }
          }
        } else if (this.type == 'marker') {
          this.mouseTool.close();
        }
      } else {
        // 新增
        if (this.type == 'polygon') {
          this.polygonEditor.addAdsorbPolygons(this.polygons);
          this.polygonEditor.setTarget();
          this.polygonEditor.open();
        } else if (this.type == 'polyline') {
          this.polylineEditor.setTarget();
          this.polylineEditor.open();
        } else if (this.type == 'marker') {
          this.mouseTool = new AMap.MouseTool(this.map);
          this.mouseTool.marker();
          this.mouseTool.on('draw', (e) => {
            const marker = e.obj;
            marker.setDraggable(false);
            marker.setExtData(this.markers.length);
            marker.setContent(this.getStrDom(this.markers.length, ''));
            marker.on('rightclick', (e) => {
              this.map.remove(marker);
              for (let i = 0; i < this.markers.length; i++) {
                if (this.markers[i] == marker) {
                  this.markers.splice(i, 1);
                  break;
                }
              }
            });
            this.markers.push(marker);
            this.mouseTool.close();
            this.isEdit = false;
          });
        }
      }
      this.isEdit = !this.isEdit;
    },
    // 编辑
    editWithType(type, path) {
      if (!type || !this.map) return;
      this.type = type;
      this.remove();
      if (this.type == 'polygon') {
        const _location = this.getConvertLocation(3, path, '02')
        this.createPolygons(_location);
      } else if (this.type == 'marker') {
        this.createMarkers(path);
      } else if (this.type == 'polyline') {
        const _location = this.getConvertLocation(3, path, '02')
        this.createPolylines(_location);
      }
    },
    // 提取坐标
    saveWithType(type) {
      if (!type || !this.map) return;
      this.isEdit && this.onClickSE();
      let list = [];
      if (this.type == 'polygon') {
        list = this.polygons.map((p) => {
        //   return p._opts.path;
            return this.getConvertLocation(2, p._opts.path, '84')
        });
      } else if (this.type == 'marker') {
        list = this.markers.map((m) => {
          const point = m.getPosition();
          const inputDom = document.getElementById(m.getExtData());
          const _location = this.getConvertLocation(1, [point.lng, point.lat], '84')
          return { point: _location, name: inputDom.value || '' };
        });
      } else if (this.type == 'polyline') {
        list = this.polylines.map((p) => {
        //   return p._opts.path;
            return this.getConvertLocation(2, p._opts.path, '84')
        });
      }
      this.remove();
      this.type = null;
      return list.length ? JSON.stringify(list) : '';
    },
    // 初始化地图
    initMap() {
      console.log('初始化地图：', this.map);
      if (this.map) return;
      const locationCenter = this.$store.state.locationCenter;
      this.map = new AMap.Map(this.mapId, {
        // mapStyle: this.sideTheme == 'theme-dark' ? 'amap://styles/dark' : 'amap://styles/normal',
        viewMode: '2D', //是否为3D地图模式
        zoom: 12, //初始化地图级别
        center: locationCenter //初始化地图中心点位置
      });
      // 卫星地图切换
      this.map.addControl(new AMap.MapType());
      // 输入提示
      var auto = new AMap.AutoComplete({ input: 'tipinput', output: 'output' });
      var placeSearch = new AMap.PlaceSearch({
        map: this.map
      }); //构造地点查询类
      auto.on('select', select); //注册监听，当选中某条记录时会触发
      function select(e) {
        placeSearch.setCity(e.poi.adcode);
        placeSearch.search(e.poi.name); //关键字查询查询
      }
      this.drawGSRegion();

      this.polygons = [];
      this.polylines = [];
      this.markers = [];
      this.polygonStyle = {
        strokeColor: '#f00',
        strokeOpacity: 0.9,
        strokeWeight: 2,
        fillColor: '#ff0',
        fillOpacity: 0.5,
        zIndex: 999
      };
      this.polylineStyle = {
        strokeColor: '#FF33FF',
        strokeOpacity: 0.9,
        strokeWeight: 6,
        zIndex: 999
      };

      this.polygonEditor = new AMap.PolygonEditor(this.map);
      this.polylineEditor = new AMap.PolylineEditor(this.map);
    },
    // 创建面
    createPolygons(path) {
      let list = [];
      try {
        list = path ? JSON.parse(path) : [];
      } catch (e) {
        console.log('JSON解析失败：', path);
      }
      if (!list.length || !this.map) return;
      this.polygons && this.map.remove(this.polygons);
      this.polygons = [];
      /* 调用时 已转gcj02 */
      // 循环创建面
      list.map((item) => {
        const polygon = new AMap.Polygon({
          // 转经纬度 item.map((point) => this.GPS.WGS84toGCJ02(...point))
          path: item,
          ...this.polygonStyle
        });
        polygon.on('rightclick', this.rightClickByPolygon);
        polygon.on('dblclick', this.dblClickByPolygon);
        this.polygons.push(polygon);
      });
      this.map.add(this.polygons);
      this.map.setFitView(this.polygons);
    },
    // 创建点位
    createMarkers(path) {
      let list = [];
      try {
        list = path ? JSON.parse(path) : [];
      } catch (e) {
        console.log('JSON解析失败：', e);
      }
      if (!list.length || !this.map) return;
      this.markers && this.map.remove(this.markers);
      this.markers = [];
      // 循环创建
      list.map((item, index) => {
        const _location = this.getConvertLocation(1, item.point, '02')
        const marker = new AMap.Marker({
          position: _location,
          title: item.name || '地点',
          draggable: false,
          extData: index,
          offset: [-50, -58],
          content: this.getStrDom(index, item.name)
        });
        marker.on('rightclick', (e) => {
          this.map.remove(marker);
          for (let i = 0; i < this.markers.length; i++) {
            if (this.markers[i] == marker) {
              this.markers.splice(i, 1);
              break;
            }
          }
        });

        // marker.on("dblclick", e => {
        //   marker.setDraggable(true)
        // })
        this.markers.push(marker);
      });
      this.map.add(this.markers);
      this.map.setFitView(this.markers);
    },
    // 创建线
    createPolylines(path) {
      let list = [];
      try {
        list = path ? JSON.parse(path) : [];
      } catch (e) {
        console.log('JSON解析失败：', path);
      }
      if (!list.length || !this.map) return;
      this.polylines && this.map.remove(this.polylines);
      this.polylines = [];
      // 循环创建
      list.map((item) => {
        var polyline = new AMap.Polyline({
          path: item,
          ...this.polylineStyle
        });
        polyline.on('rightclick', this.rightClickByPolyline);
        polyline.on('dblclick', this.dblClickByPolyline);
        this.polylines.push(polyline);
      });
      this.map.add(this.polylines);
      this.map.setFitView(this.polylines);
    },
    // 右键点击线，去删除
    rightClickByPolyline(e) {
      const polyline = e.target;
      this.isEdit && this.onClickSE();
      this.$modal.confirm('确定删除此对象').then(() => {
        this.map.remove(polyline);
        for (let i = 0; i < this.polylines.length; i++) {
          if (this.polylines[i] == polyline) {
            this.polylines.splice(i, 1);
            break;
          }
        }
      });
    },
    // 双击点击线，去编辑
    dblClickByPolyline(e) {
      const polyline = e.target;
      this.isEdit && this.onClickSE();
      this.isEdit = true;
      this.polylineEditor.setTarget(polyline);
      this.polylineEditor.open();
    },
    // 右键点击面，去删除
    rightClickByPolygon(e) {
      const polygon = e.target;
      this.isEdit && this.onClickSE();
      this.$modal.confirm('确定删除此对象').then(() => {
        this.map.remove(polygon);
        for (let i = 0; i < this.polygons.length; i++) {
          if (this.polygons[i] == polygon) {
            this.polygons.splice(i, 1);
            break;
          }
        }
      });
    },
    // 双击点击面，去编辑
    dblClickByPolygon(e) {
      const polygon = e.target;
      console.log('点击了面', polygon);
      this.isEdit && this.onClickSE();
      this.isEdit = true;
      this.polygonEditor.addAdsorbPolygons(this.polygons);
      this.polygonEditor.setTarget(polygon);
      this.polygonEditor.open();
    },
    // 大头针Dom
    getStrDom(index, value = '') {
      const str = `<div class="map-marker-content">
          <input class="input" id="${index}" type="text" value='${value}' autocomplate="false" placeholder="请输入内容"">
          <img class="img" src="${require('@/assets/images/mark_bs.png')}" alt="">
        </div>`;
      return str;
    },
    // 删除绘制
    remove() {
      if (this.polygons && this.polygons.length) {
        this.map.remove(this.polygons);
        this.polygons = [];
      }
      if (this.markers && this.markers.length) {
        this.map.remove(this.markers);
        this.markers = [];
      }
      if (this.polylines && this.polylines.length) {
        this.map.remove(this.polylines);
        this.polylines = [];
      }
    },
    // 重置地图状态
    resetMap() {
      if (!this.map) return;
      // 停止编辑
      this.isEdit && this.onClickSE();
      // 删除所有编辑
      this.remove();
    },
    // 绘制拱墅区范围
    drawGSRegion() {
      const district = new AMap.DistrictSearch({
        subdistrict: 0, //获取边界不需要返回下级行政区
        extensions: 'all', //返回行政区边界坐标组等具体信息
        level: 'district' //查询行政级别为 市
      });

      district.search('嘉兴市', (status, result) => {
        if (this.GSPolygon) {
          this.map.remove(this.GSPolygon); //清除上次结果
          this.GSPolygon = null;
        }
        var bounds = result.districtList[0].boundaries;
        if (bounds) {
          //生成行政区划polygon
          for (var i = 0; i < bounds.length; i += 1) {
            //构造MultiPolygon的path
            bounds[i] = [bounds[i]];
          }
          this.GSPolygon = new AMap.Polygon({
            strokeWeight: 2,
            path: bounds,
            strokeStyle: 'dashed',
            fillOpacity: 0,
            fillColor: '#80d8ff',
            strokeColor: '#0000ff',
            bubble: true,
            zIndex: 1
          });
          this.map.add(this.GSPolygon);
          this.map.setFitView(this.GSPolygon); //视口自适应
        }
      });
    },
    drawConstomPolygon(key, data, opts={}) {
      if(polygonLayer[key]) {
        this.map.remove(polygonLayer[key])
        polygonLayer[key] = null
      }

      if(!data || data.length==0) return;
      const polygons = []
      const options = {
        strokeColor: '#808003',
        strokeWeight: 1,
        fillColor: '#66ccff',
        fillOpacity: 0.3,
        zIndex: 1
      }

      Object.assign(options, opts)
      data.map(item=> {
        if(item.locationArea) {
          const paths = JSON.parse(item.locationArea)
          paths.map(path => {
            const _location = this.getConvertLocation(2, path, '02')
            const polygon = new AMap.Polygon({
              path: _location,
              ...options
            })
            polygons.push(polygon)
          })
        }
      })
      polygonLayer[key] = polygons;
      this.map.add(polygons)
    }
  }
};
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  .edit {
    position: absolute;
    top: 20px;
    left: 350px;
    padding: 15px 25px;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
    cursor: pointer;
  }

  .top {
    position: absolute;
    top: 20px;
    left: 20px;
    padding: 10px;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
  }
  .search {
    display: flex;

    .tip {
      padding: 0 5px;
      color: #495057;
      text-align: center;
      height: 30px;
      line-height: 30px;
      white-space: nowrap;
      background-color: #e9ecef;
      border: 1px solid #ced4da;
      border-right: none;
      border-radius: 5px;
      border-bottom-right-radius: 0;
      border-top-right-radius: 0;
    }
    input {
      outline-style: none;
      width: 200px;
      border-radius: 5px;
      border: 1px solid #ced4da;
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
      background: #fff;
      padding: 5px;
      margin: 0;
    }
  }
  .map {
    width: 100%;
    height: 100%;
    min-width: 20px;
    min-height: 20px;
    padding: 0;
    margin: 0;
    box-sizing: border-box;
  }
}
</style>
<style lang="scss">
.map-marker-content {
  width: 100px;
  height: 60px;
  text-align: center;
  .input {
    width: 100%;
    height: 25px;
    margin-bottom: 4.5px;
    text-align: center;
  }
  .img {
    width: 19px;
    height: 31.5px;
    margin: 0 auto;
  }
}
</style>
